

/**
 epgmemory.js 「テレビ番組表の記録」で利用するjsファイル
 @author winter.daydreams@gmail.com (satmat twitter: satellitesat)
 */
var SATMAT_NICOJK = SATMAT_NICOJK || {};


/**
 「テレビ番組表の記録」用名前空間の生成
 */
SATMAT_NICOJK.namespace('SATMAT_NICOJK.epgmemory.main');
//SATMAT_NICOJK.epgmemory.NICOJK_BASE_URL = "http://jk.nicovideo.jp";
SATMAT_NICOJK.epgmemory.main = (function() {
  'use strict';
  var util = SATMAT_NICOJK.util,
      createDateFromUrl = {},
      showNextPrevDayEpgLink = {},
      createNicojkLink = {},
      visibleNicojkLink = {},
      hiddenNicojkLink = {},
      chid2bcinfo = {};


  /**
   * 「過去番組表の記録」番組表ページのURLからDateオブジェクトを生成する.
   * @param {String} 番組表ページのURL.
   * @param {Date} 番組表のページURLから生成したDateオブジェクト.
   * */
  createDateFromUrl = function(url_str) {
    var url_split = [],
        year = '',
        month = '',
        day_split = [],
        day = '',
        date_obj = {};
        

    if (url_str === null){
      throw new Error('引数\'url_str\'がnullである。');
    } else if (typeof url_str !== 'string'){
      throw new Error('引数\'url_str\'がStringでない。');
    }
    
    /* http://timetable.yanbe.net/html/xx/yyyy/MM/dd_x.html?xx */
    url_split = url_str.split('/');
    if(url_split.length < 8){
      throw new Error('\'url_str\'URL文字列が不正な可能性。', url_str);
    }

    year = url_split[5];
    month = url_split[6] - 1; /* 月は0始まりなので-1する */

    day_split = url_split[7].split('_');
    if(day_split.length < 2){
      throw new Error('\'url_str\'URL文字列が不正な可能性。', url_str);
    }
    
    day = day_split[0];

    /* 番組表で00:00は前日扱いとするので、12時としてdayと同じ日扱いにする */
    date_obj = new Date(year, month, day, 12);
    return date_obj;
  };

  /**
   * 前日と翌日のへのリンクを"表示切替"メニューに表示する。
   * @param {void} void 引数なし.
   * @return {void} void 明示的な返り値なし.
   * */
  showNextPrevDayEpgLink = function() {
    var title_menu_div = {},
        prev_day_span = {},
        prev_day_anchor = {},
        next_day_span = {},
        next_day_anchor = {},
        base_date = {};


    title_menu_div = document.getElementsByClassName('title_menu');
    if (title_menu_div.length === 0) {
      throw new Error('クラス名が\'title_menu\'のdivが見つからない。');
    }

    base_date = createDateFromUrl(location.href);

    /* 前日 */
    title_menu_div[0].insertBefore(document.createElement('br'),
                                   title_menu_div[0].firstChild);
    prev_day_span = document.createElement('span');
    prev_day_span.id = 'prev_day_epg_span';
    prev_day_anchor = document.createElement('a');
    prev_day_anchor.id = 'prev_day_epg_anchor';
    prev_day_anchor.href = util.getEpgmemoryAnchorStr(-1, base_date);
    prev_day_anchor.innerText = '<<昨日';
    prev_day_span.appendChild(prev_day_anchor);
    prev_day_span.appendChild(document.createTextNode(' '));

    /* 翌日 */
    next_day_span = document.createElement('span');
    next_day_span.id = 'next_day_epg_span';
    next_day_span.style.textAlign = 'right';
    next_day_anchor = document.createElement('a');
    next_day_anchor.id = 'next_day_epg_anchor';
    next_day_anchor.href = util.getEpgmemoryAnchorStr(+1, base_date);
    next_day_anchor.innerText = ' 翌日>>';
    prev_day_span.appendChild(document.createTextNode(' '));
    next_day_span.appendChild(next_day_anchor);


    title_menu_div[0].insertBefore(next_day_span, title_menu_div[0].firstChild);
    title_menu_div[0].insertBefore(prev_day_span, title_menu_div[0].firstChild);

    return true;
  };


  /**
   *  番組のIDからニコニコ実況へのリンクURLを生成する.
   * @param {String} content_id 「テレビ番組表の記録」 コンテンツID.
   * @return {String} ニコニコ実況へのURL.
   */
  createNicojkLink = function(content_id) {
    var chid = 0,
        starttime_no = 0,
        jkinfo = 0,
        year = 0,
        month = 0,
        day = 0,
        hour = 0,
        minute = 0,
        id_date = {},
        now_date = new Date(),
        end_date = {},
        nicojk_url = '';

    // console.log(content_id);

    chid = content_id.substring(0, 9);
    starttime_no = content_id.substring(9, 21);
    jkinfo = chid2bcinfo(chid);

    console.log(chid, starttime_no, jkinfo);

    if (typeof jkinfo === 'undefined' ||
        jkinfo.jknum === '') {

      console.debug(
          chid + " couldn't be mapped jk number. return default URL."
      );
      return (SATMAT_NICOJK.defs.NICOJK_BASE_URL);
    }

    id_date = new Date(
        parseInt(starttime_no.substring(0, 4), 10),      //yyyy
        parseInt(starttime_no.substring(4, 6), 10) - 1,  //MM ( 0-11 )
        parseInt(starttime_no.substring(6, 8), 10),      //dd
        parseInt(starttime_no.substring(8, 10), 10),     //hh
        parseInt(starttime_no.substring(10, 12), 10),    //mm
        0                                                //ss
        );

    if (id_date.getTime() < now_date.getTime()) { // past and current

      end_date = new Date();
      end_date.setTime(id_date.getTime() + 1800 * 1000);        // 30分=1800秒加算
      nicojk_url =
          SATMAT_NICOJK.defs.NICOJK_BASE_URL + '/log/' +
          jkinfo.jknum + '/' +
          id_date.getFullYear().toString() +
          util.toTwoDigits(id_date.getMonth() + 1) +
          util.toTwoDigits(id_date.getDate()) +
          util.toTwoDigits(id_date.getHours()) +
          util.toTwoDigits(id_date.getMinutes()) +
          '00-' +
          end_date.getFullYear().toString() +
          util.toTwoDigits(end_date.getMonth() + 1) +
          util.toTwoDigits(end_date.getDate()) +
          util.toTwoDigits(end_date.getHours()) +
          util.toTwoDigits(end_date.getMinutes()) +
          '00';

    }else {  // future
      nicojk_url = SATMAT_NICOJK.defs.NICOJK_BASE_URL + '/watch/' +
          jkinfo.jknum;
    }

    console.log(nicojk_url);
    return nicojk_url;
  };


  visibleNicojkLink = function(e) {
    var nicojklink = {},
        nicojklink_text = '',
        nicojk_img = {},
        program_links = [],
        program_links_len = 0,
        i = 0;

    if (e.target.nodeName.toLowerCase() === 'td') {
      // 既にリンクを表示済かどうかを確認する
      if (e.target.lastChild &&
          e.target.lastChild.href &&
          e.target.lastChild.href.search(
          SATMAT_NICOJK.defs.NICOJK_BASE_URL
          ) !== -1) {
        return;
      }

      nicojklink = document.createElement('a');
      nicojk_img = document.createElement('img');
      nicojk_img.src = 'http://jk.nicovideo.jp/images/nico.ico';
      nicojk_img.style = 'width:12px; height:12px;';
      nicojklink.appendChild(nicojk_img);

      nicojklink_text = document.createTextNode(' [ニコニコ実況で表示]');
      nicojklink.appendChild(nicojklink_text);
      nicojklink.target = 'blank';
      nicojklink.className = 'program_title';

      program_links = e.target.getElementsByTagName('a');
      program_links_len = program_links.length;

      if (program_links_len === 0) {
        return;
      }else {
        for (i = 0; i < program_links_len; i++) {
          // console.log(program_links[i].href);
          if (program_links[i].href &&
              program_links[i].href.match(/([0-9]+$)/i)) {
            nicojklink.href = createNicojkLink(RegExp.lastMatch);
          }
        }
      }

      e.target.appendChild(document.createElement('br'));
      e.target.appendChild(nicojklink);
    }
  };


  hiddenNicojkLink = function(e) {
    var from_td = {},
        to_td = {};

    if (e.target && e.target.nodeName) {
      if (e.target.nodeName.toLowerCase() === 'a') {
        if (e.target.parentNode &&
            e.target.parentNode.nodeName.toLowerCase() === 'td')
        {
          from_td = e.target.parentNode;
        }
      }else if (e.target.nodeName.toLowerCase() === 'img') {
        if (e.target.parentNode &&
            e.target.parentNode.nodeName.toLowerCase() === 'td')
        {
          from_td = e.target.parentNode;
        }
        else if (e.target.parentNode.parentNode &&
                 e.target.parentNode.parentNode.nodeName &&
                 e.target.parentNode.parentNode.nodeName.
                 toLowerCase() === 'td')
        {
          from_td = e.target.parentNode.parentNode;
        }
      }else if (e.target.nodeName.toLowerCase() === 'td') {
        from_td = e.target;
      }
    }

    if (e.relatedTarget && e.relatedTarget.nodeName) {
      if (e.relatedTarget.nodeName.toLowerCase() === 'a') {
        if (e.relatedTarget.parentNode &&
            e.relatedTarget.parentNode.nodeName.toLowerCase() === 'td') {
          to_td = e.relatedTarget.parentNode;
        }
      }else if (e.relatedTarget.nodeName.toLowerCase() === 'img') {
        if (e.relatedTarget.parentNode &&
            e.relatedTarget.parentNode.nodeName.toLowerCase() === 'td') {
          to_td = e.relatedTarget.parentNode;
        }else if (e.relatedTarget.parentNode.parentNode &&
                  e.relatedTarget.parentNode.parentNode.nodeName &&
                  e.relatedTarget.parentNode.parentNode.nodeName.
                  toLowerCase() === 'td')
        {
          to_td = e.relatedTarget.parentNode.parentNode;
        }
      }else if (e.relatedTarget.nodeName.toLowerCase() === 'td') {
        to_td = e.relatedTarget;
      }
    }

    if (from_td && to_td && from_td === to_td) {
      // 同じセル内への移動であれば何もしない
    }else {
      if (from_td && from_td.lastChild && from_td.lastChild.href &&
          from_td.lastChild.href.search(
          SATMAT_NICOJK.defs.NICOJK_BASE_URL
          ) !== -1)
      {
        from_td.removeChild(from_td.lastChild); // ニコニコ実況へのリンク
        from_td.removeChild(from_td.lastChild); // br
      }
    }
  };


  /**
   * common.jsのepgmemory.chid2bcinfo()
   * を呼び出し、chidを放送局情報に変換する。
   * @param {String} chid チャンネルID.
   * @return {Object} 放送局情報.
   * */
  chid2bcinfo = util.chid2bcinfo;


  return {

    init: function() {
      var tds = {},
          tds_length = 0,
          i = 0;

      /* 昨日、明日へのリンク表示  */
      showNextPrevDayEpgLink();

      tds = document.getElementsByTagName('td');
      tds_length = tds.length;
      for (i = 0; i < tds_length; i++) {
        if (tds[i].className === 'program_td') {
          tds[i].onmouseover = visibleNicojkLink;
          tds[i].onmouseout = hiddenNicojkLink;
        }
      }
    } // init

  };

}());
